package com.lxxie.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lxxie.enums.Platform;
import com.lxxie.util.DESUtil;
import com.lxxie.util.RuralDB;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.net.ssl.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @Description TODO
 * @Date 2021/8/27 11:48
 * @Created by xielx
 */
public class UnitTest2 {
    private final static String COUNT_SQL = "select count(1) from net_rural_unit t where dw_lx='01' and isshangb=9 and isshenh=9 and isdel=0 and status=1";
    private final static String QUERY_SQL = "select * from (select dw_code xzqh,dw_name XZQHMC,dmz GBDM,dw_name_pre MCQZ,fazjg fzjg,rownum rw from net_rural_unit t where dw_lx='01' and isshangb=9 and isshenh=9 and isdel=0 and status=1) aa where aa.rw>%d and aa.rw<=%d ";
    private final static String DELETE_SQL = "delete from net_rural_gab.JZPT_UNIT where XZQH=:XZQH";
    private final static String INSERT_SQL = "insert into net_rural_gab.JZPT_UNIT(XZQH, XZQHMC, GBDM, MCQZ, FZJG) values (:XZQH, :XZQHMC, :GBDM, :MCQZ, :FZJG)";
    private final static NamedParameterJdbcTemplate jdbcTemplate = RuralDB.getJdbcTemplate();
    private final static Map<String, Integer> result = new ConcurrentHashMap<>();

    private static final ThreadPoolExecutor pool = new ThreadPoolExecutor(100, 100, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(5000));

    public static void main(String[] args) throws IOException, InterruptedException {
        int index = 0;
        CountDownLatch totalLacth = new CountDownLatch(Platform.values().length);
        for (Platform plat : Platform.values()) {
            pool.execute(() -> {
                try {
                    //CloseableHttpClient httpclient = HttpClients.createDefault();
                    TrustManager[] trustManager = new TrustManager[1];
                    TrustManager tm = new miTM();
                    trustManager[0] = tm;
                    SSLContext sc = SSLContext.getInstance("SSL");
                    sc.init(null, trustManager, null);
                    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                    CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLHostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String s, SSLSession sslSession) {
                            return true;
                        }
                    }).setSSLContext(sc).build();
                    String domain = plat.getUrl();
                    HttpPost post = new HttpPost(domain + "/risinfo/system");
                    List<BasicNameValuePair> params = new ArrayList<>();
                    params.add(new BasicNameValuePair("type", "duck"));
                    params.add(new BasicNameValuePair("data", new String(Base64.encodeBase64(DESUtil.encrypt(COUNT_SQL.getBytes())))));
                    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
                    post.setEntity(entity);
                    CloseableHttpResponse resp = httpclient.execute(post);
                    JSONObject json = JSON.parseObject(EntityUtils.toString(resp.getEntity()));
                    if (json.getInteger("outOk") != 1) {
                        return;
                    }
                    int total = json.getJSONArray("rows1").getJSONObject(0).getInteger("COUNT(1)");
                    result.put(plat.getSfdm(), total);

                    CountDownLatch latch = new CountDownLatch(total / 1000 + ((total % 1000) > 0 ? 1 : 0));
                    int i = 0;
                    for (; i < total / 1000; i++) {
                        pool.execute(new ListRunalbe(domain, i * 1000, (i + 1) * 1000, httpclient, latch));
                    }
                    if (total % 1000 > 0) {
                        pool.execute(new ListRunalbe(domain, i * 1000, total, httpclient, latch));
                    }
                    latch.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    totalLacth.countDown();
                }
            });

        }
        totalLacth.await();
        for (Platform value : Platform.values()) {
            System.out.println(value.getSfmc() + "\t" + result.get(value.getSfdm()));
        }
    }

    public static class ListRunalbe implements Runnable {
        private String domain;
        private int start;
        private int end;
        private CloseableHttpClient httpclient;
        private CountDownLatch latch;

        public ListRunalbe(String domain, int start, int end, CloseableHttpClient httpclient, CountDownLatch latch) {
            this.domain = domain;
            this.start = start;
            this.end = end;
            this.httpclient = httpclient;
            this.latch = latch;
        }

        @Override
        public void run() {
            TransactionStatus status = null;
            try {
                HttpPost post = new HttpPost(domain + "/risinfo/system");
                List<BasicNameValuePair> params = new ArrayList<>();
                params.add(new BasicNameValuePair("type", "duck"));
                String enstr = new String(Base64.encodeBase64(DESUtil.encrypt(String.format(QUERY_SQL, start, end).getBytes())));
                params.add(new BasicNameValuePair("data", enstr));
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
                post.setEntity(entity);
                CloseableHttpResponse resp = httpclient.execute(post);
                JSONObject json = JSON.parseObject(EntityUtils.toString(resp.getEntity()));
                JSONArray rows = json.getJSONArray("rows1");
                JSONObject[] args = rows.toArray(new JSONObject[rows.size()]);
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
                status = RuralDB.beginTrans();
                jdbcTemplate.batchUpdate(DELETE_SQL, args);
                jdbcTemplate.batchUpdate(INSERT_SQL, args);
                RuralDB.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                RuralDB.rollback(status);
            } finally {
                latch.countDown();
            }
        }
    }

    static class miTM implements TrustManager, javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(
            java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(
            java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(
            java.security.cert.X509Certificate[] certs, String authType)
            throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(
            java.security.cert.X509Certificate[] certs, String authType)
            throws java.security.cert.CertificateException {
            return;
        }
    }
}
